﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.NetworkInformation;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;

namespace zy_simu.Data
{
    public class HexFileParser
    {
        public byte[] image = new byte[256*1024];
        public int image_size = 0;

        private int base_address = 0;
        private int current_address = 0;

        public async Task Parser(Stream stream)
        {
            base_address = 0;
            current_address = -1;
            image_size = 0;

            int len = 0;
            try
            {
                using (StreamReader reader = new StreamReader(stream))
                {
                    string line;
                    while ((line = await reader.ReadLineAsync()) != null)
                    {
                        if (!line.StartsWith(":")) // format error
                        {
                            Console.WriteLine("Error: Line start without ':'.");
                            return;
                        }
                        // Extract the length, address, and type fields
                        int length = int.Parse(line.Substring(1, 2), System.Globalization.NumberStyles.HexNumber);
                        int address = int.Parse(line.Substring(3, 4), System.Globalization.NumberStyles.HexNumber);
                        int type = int.Parse(line.Substring(7, 2), System.Globalization.NumberStyles.HexNumber);
                        switch (type)
                        {
                            case 0: // Data Record
                                {
                                    if ((base_address + address) != current_address && current_address != -1) // address not contiguous, only support a mirror image of a single contiguous address
                                    {
                                        Console.WriteLine("Error: only support a mirror image of a single contiguous address");
                                        return;
                                    }
                                    current_address = base_address + address + length;
                                    // Extract the data field based on the length
                                    string dataField = line.Substring(9, length * 2);
                                    for (int i = 0; i < length; i++)
                                    {
                                        if (len >= 256 * 1024)
                                        {
                                            Console.WriteLine("Error: image size is larger than 256kB");
                                            return;
                                        }
                                        image[len] = byte.Parse(dataField.Substring(i * 2, 2), System.Globalization.NumberStyles.HexNumber);
                                        len++;
                                    }
                                    break;
                                }
                            case 1: // End of File Record
                                break;
                            case 2: // Extended Segment Address Record
                                {
                                    ushort seg = ushort.Parse(line.Substring(9, 4), System.Globalization.NumberStyles.HexNumber);
                                    base_address = seg << 4;
                                }
                                break;
                            case 3: // Start Segment Address Record
                                break;
                            case 4: // Extended Linear Address Record
                                {
                                    ushort seg = ushort.Parse(line.Substring(9, 4), System.Globalization.NumberStyles.HexNumber);
                                    base_address = seg << 16;
                                }
                                break;
                            case 5: // Start Linear Address Record
                                break;
                            default:
                                Console.WriteLine("Error: Invalid Record Type");
                                Debug.Assert(false);
                                return;
                        }
                    }

                }
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error reading file: {ex.Message}");
                image_size = 0;
            }
            image_size = len;
        }
        //public HexFileParse(string filePath)
        //{
        //    try
        //    {
        //        using (StreamReader reader = new StreamReader(filePath))
        //        {
        //            this.HexFileParse(reader);
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        Console.WriteLine($"Error reading file: {ex.Message}");
        //        image_size = 0;
        //    }

        //}
    }
}
